package com.muyu.util;

import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.mock.web.MockMultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: QRCodeUtils
 * @Author: Zirun.Xin
 * @Date: 2025/1/9 13:53
 * @Version: 1.0
 * @Description: 二维码操作工具类
 */
@Slf4j
@Component
public class QRCodeUtils {

    /**
     * 生成二维码图片
     *
     * @param text 需要转换为二维码的内容
     * @param width 图片宽度
     * @param height 图片高度
     * @param filePath 文件保存路径
     * @throws WriterException ZXing编码异常
     * @throws IOException IO异常
     */
    public static void generateQRCodeImage(String text, int width, int height, String filePath)
            throws WriterException, IOException {
        // 生成位矩阵（BitMatrix）
        BitMatrix bitMatrix = generateQRCodeBitMatrix(text, width, height);
        // 获取指定文件路径的对象
        Path path = FileSystems.getDefault().getPath(filePath);
        // 将生成的位矩阵写入到指定路径的PNG格式文件中
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
    }

    /**
     * 生成二维码并返回MultipartFile
     *
     * @param text 需要转换为二维码的内容
     * @param width 图片宽度
     * @param height 图片高度
     * @return MultipartFile类型的二维码图片
     * @throws WriterException ZXing编码异常
     * @throws IOException IO异常
     */
    public static MultipartFile generateQRCodeAsMultipartFile(String text, int width, int height)
            throws WriterException, IOException {
        // 生成位矩阵（BitMatrix）
        BitMatrix bitMatrix = generateQRCodeBitMatrix(text, width, height);
        // 将BitMatrix写入ByteArrayOutputStream
        ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream();
        MatrixToImageWriter.writeToStream(bitMatrix, "PNG", pngOutputStream);
        byte[] imageData = pngOutputStream.toByteArray();

        // 创建MockMultipartFile对象
        return new MockMultipartFile("qrcode", "qrcode.png", "image/png", new ByteArrayInputStream(imageData));
    }

    /**
     * 解码二维码图片
     *
     * @param filePath 二维码图片路径
     */
    public static void decodeQRCode(String filePath) {
        File file = new File(filePath);
        BufferedImage image;
        try {
            image = ImageIO.read(file);
            if (image == null) {
                log.info("无法读取文件：{}", filePath);
                return;
            }
            LuminanceSource source = new BufferedImageLuminanceSource(image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

            // 设置解码提示，例如字符集
            Map<DecodeHintType, Object> hints = new HashMap<>();
            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");

            Result result = new MultiFormatReader().decode(bitmap, hints);
            log.info("二维码内容为：{}", result.getText());
        } catch (IOException e) {
            log.info("读取文件时出错：{}", e.getMessage());
        } catch (NotFoundException e) {
            log.info("未找到二维码：{}", e.getMessage());
        }
    }

    /**
     * 根据提供的文本内容、宽度和高度生成二维码的位矩阵（BitMatrix）。
     *
     * @param text 需要编码到二维码中的文本信息，支持使用UTF-8编码的字符串。
     * @param width 生成的二维码图片的宽度，单位为像素。
     * @param height 生成的二维码图片的高度，单位为像素。
     * @return 返回包含二维码图案信息的BitMatrix对象。
     * @throws WriterException 如果在生成二维码过程中发生错误，则抛出此异常。
     */
    private static BitMatrix generateQRCodeBitMatrix(String text, int width, int height) throws WriterException {
        // 设置二维码纠错级别参数
        Map<EncodeHintType,Object> hintMap = new EnumMap<>(EncodeHintType.class);
        hintMap.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

        // 创建QRCodeWriter实例，用于生成二维码
        QRCodeWriter qrCodeWriter = new QRCodeWriter();
        // 使用QRCodeWriter根据提供的文本、格式、宽度和高度生成位矩阵（BitMatrix）
        return qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hintMap);
    }
}
